home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 14 / IOPROG_14.ISO / soft / sdkjava / sdkjava.exe / SDKJava.cab / Samples / Debugger / C++ Debugger / JDebug.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-05  |  18.7 KB  |  817 lines

  1. /*++
  2.  
  3. Copyright (c) 1998  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.    jdebug.cpp
  8.  
  9. Abstract:
  10.  
  11.    Java debugger class implementation.
  12.  
  13.    The C++ debugger sample preforms the following steps:
  14.  
  15.     1) Connects to the debug manager.
  16.     2) Runs the Java debuggee applet.
  17.     3) Watches for the debuggee's Java VM to be created, and puts up a message box.
  18.     4) Connects to the debuggee's Java VM.
  19.     5) Watches for the debuggee class to be loaded.
  20.     6) Sets a breakpoint in a method in the debuggee class.
  21.     7) Watches for the breakpoint to be hit, and puts up a message box.
  22.     8) Clears the breakpoint.
  23.     9) Watches for the debuggee's Java VM to be destroyed, and puts up a message box.
  24.    10) Disconnects from the debuggee's Java VM.
  25.    11) Disconnects from the debug manager.
  26.    12) Exits.
  27.  
  28. --*/
  29.  
  30.  
  31. /* Headers
  32.  **********/
  33.  
  34. #include "project.hpp"
  35.  
  36. #include <javadbg.h>
  37. #include <jdbgguid.h>
  38.  
  39. #include "refcount.hpp"
  40.  
  41.  
  42. /* Classes
  43.  **********/
  44.  
  45. // sample Java debugger class
  46.  
  47. class JavaDebugger : public RefCount,
  48.                      public IRemoteDebugManagerCallback,
  49.                      public IRemoteProcessCallback
  50. {
  51. private:
  52.    /* Fields
  53.     *********/
  54.  
  55.    // debug manager
  56.    IRemoteDebugManager *m_pirdm;
  57.  
  58.    // remote process
  59.    IRemoteProcess *m_pirp;
  60.  
  61.    // debuggee class name
  62.    LPWSTR m_pwszDebugClass;
  63.  
  64.    /* Methods
  65.     **********/
  66.  
  67.    UINT RunMessageLoop(void);
  68.    void QuitMessageLoop(UINT uResult);
  69.  
  70. public:
  71.    /* Methods
  72.     **********/
  73.  
  74.    JavaDebugger(void);
  75.    ~JavaDebugger(void);
  76.    HRESULT Initialize(IRemoteDebugManager *pirdm);
  77.    void Terminate(void);
  78.    HRESULT Debug(LPCSTR pcszDebugClass);
  79.  
  80.    // IRemoteDebugManagerCallback methods
  81.  
  82.    HRESULT STDMETHODCALLTYPE ProcessCreateEvent(IRemoteProcess *pirpNew, IRemoteProcess *pirpParent);
  83.  
  84.    // IRemoteProcessCallback methods
  85.  
  86.    HRESULT STDMETHODCALLTYPE DebugStringEvent(IRemoteThread *pirth, LPCWSTR pcwszDebugMsg);
  87.    HRESULT STDMETHODCALLTYPE CodeBreakpointEvent(IRemoteThread *pirth);
  88.    HRESULT STDMETHODCALLTYPE DataBreakpointEvent(IRemoteThread *pirth, IRemoteObject *piro);
  89.    HRESULT STDMETHODCALLTYPE ExceptionEvent(IRemoteThread *pirth, IRemoteClassField *pircfException, EXCEPTIONKIND exk);
  90.    HRESULT STDMETHODCALLTYPE StepEvent(IRemoteThread *pirth);
  91.    HRESULT STDMETHODCALLTYPE CanStopEvent(IRemoteThread *pirth);
  92.    HRESULT STDMETHODCALLTYPE BreakEvent(IRemoteThread *pirth);
  93.    HRESULT STDMETHODCALLTYPE ThreadCreateEvent(IRemoteThread *pirth);
  94.    HRESULT STDMETHODCALLTYPE ThreadDestroyEvent(IRemoteThread *pirth);
  95.    HRESULT STDMETHODCALLTYPE ThreadGroupCreateEvent(IRemoteThread *pirth, IRemoteThreadGroup *pirthg);
  96.    HRESULT STDMETHODCALLTYPE ThreadGroupDestroyEvent(IRemoteThread *pirth, IRemoteThreadGroup *pirthg);
  97.    HRESULT STDMETHODCALLTYPE ClassLoadEvent(IRemoteThread *pirth, IRemoteClassField *pircfClass);
  98.    HRESULT STDMETHODCALLTYPE ClassUnloadEvent(IRemoteThread *pirth, IRemoteClassField *pircfClass);
  99.    HRESULT STDMETHODCALLTYPE ProcessDestroyEvent(IRemoteThread *pirth);
  100.    HRESULT STDMETHODCALLTYPE TraceEvent(IRemoteThread *pirth);
  101.    HRESULT STDMETHODCALLTYPE LoadCompleteEvent(IRemoteThread *pirth);
  102.  
  103.    // IUnknown methods
  104.  
  105.    DEFINE_DELEGATED_REFCOUNT_ADDREF(JavaDebugger);
  106.    DEFINE_DELEGATED_REFCOUNT_RELEASE(JavaDebugger);
  107.    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, PVOID *ppvObject);
  108. };
  109.  
  110.  
  111. /* Module Constants
  112.  *******************/
  113.  
  114. #pragma data_seg(DATA_SEG_READ_ONLY)
  115.  
  116. const char SPACE                 = ' ';
  117. const char TAB                   = '\t';
  118. const char QUOTE                 = '\'';
  119. const char QUOTES                = '"';
  120.  
  121. const char s_cszMsgBoxTitle[]    = "Sample Java Debugger";
  122.  
  123. const char s_cszDebugKey[]       = "Software\\Microsoft\\Java VM\\Debug";
  124.  
  125. const char s_cszDebugClass[]     = "Hello";
  126. const WCHAR s_cwszDebugMethod[]  = L"main";
  127. const ULONG s_ulcBreakpointPC    = 0;
  128.  
  129. #pragma data_seg()
  130.  
  131.  
  132. /* Macros
  133.  *********/
  134.  
  135. //
  136. // Compile-time type check cast macro.
  137. //
  138. #define SAFE_CAST(type, obj) \
  139.    (((type)(obj) == (obj) ? 0 : 0), (type)(obj))
  140.  
  141. //
  142. // Safely delete an object.
  143. //
  144. #define SAFE_DELETE(ptr) \
  145.    { \
  146.       if (! (ptr)) \
  147.           ; \
  148.       else \
  149.       { \
  150.           delete(ptr); \
  151.           (ptr) = NULL;  \
  152.       } \
  153.    } \
  154.  
  155.  
  156. /***************************** Private Functions *****************************/
  157.  
  158.  
  159. //
  160. // Create a dynamically allocated Unicode copy of an ANSI string.
  161. //
  162. static HRESULT ANSIToUnicode(LPCSTR pcszANSI, LPWSTR *ppwszUnicode)
  163. {
  164.    HRESULT hr = E_UNEXPECTED;
  165.    int ncchANSI;
  166.    int ncchUnicode;
  167.  
  168.    // (+ 1) for null terminator.
  169.    ncchANSI = lstrlen(pcszANSI) + 1;
  170.  
  171.    ncchUnicode = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszANSI, ncchANSI, NULL, 0);
  172.  
  173.    if (ncchUnicode > 0)
  174.    {
  175.       *ppwszUnicode = new(WCHAR[ncchUnicode]);
  176.  
  177.       if (*ppwszUnicode)
  178.       {
  179.          if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszANSI, ncchANSI, *ppwszUnicode, ncchUnicode) == ncchUnicode)
  180.             hr = S_OK;
  181.          else
  182.          {
  183.             delete(*ppwszUnicode);
  184.             *ppwszUnicode = NULL;
  185.          }
  186.       }
  187.       else
  188.          hr = E_OUTOFMEMORY;
  189.    }
  190.    else
  191.       *ppwszUnicode = NULL;
  192.  
  193.    return(hr);
  194. }
  195.  
  196.  
  197. //
  198. // Skip over the white space at the beginning of a string.
  199. //
  200. LPCSTR SkipWhiteSpace(LPCSTR pcsz)
  201. {
  202.    while (*pcsz == SPACE ||
  203.           *pcsz == TAB)
  204.       pcsz = CharNext(pcsz);
  205.  
  206.    return(pcsz);
  207. }
  208.  
  209.  
  210. //
  211. // Skip over the meat at the beginning of a string.
  212. //
  213. static LPCSTR SkipNonWhiteSpace(LPCSTR pcsz)
  214. {
  215.    while (*pcsz &&
  216.           *pcsz != SPACE &&
  217.           *pcsz != TAB)
  218.       pcsz = CharNext(pcsz);
  219.  
  220.    return(pcsz);
  221. }
  222.  
  223.  
  224. //
  225. // Skip over a quoted substring at the beginning of a string.
  226. //
  227. static LPCSTR SkipQuotedArg(LPCSTR pcsz)
  228. {
  229.    char chQ;
  230.  
  231.    // Skip over quoted argument past matching quote.
  232.  
  233.    chQ = *pcsz;
  234.    pcsz = CharNext(pcsz);
  235.  
  236.    while (*pcsz &&
  237.           *pcsz != chQ)
  238.       pcsz = CharNext(pcsz);
  239.  
  240.    if (*pcsz == chQ)
  241.       pcsz = CharNext(pcsz);
  242.  
  243.    return(pcsz);
  244. }
  245.  
  246.  
  247. //
  248. // Skip over a possibly quoted substring at the beginning of a string.
  249. //
  250. static LPCSTR SkipPossiblyQuotedArg(LPCSTR pcsz)
  251. {
  252.    pcsz = SkipWhiteSpace(pcsz);
  253.  
  254.    switch (*pcsz)
  255.    {
  256.       case QUOTE:
  257.       case QUOTES:
  258.          pcsz = SkipQuotedArg(pcsz);
  259.          break;
  260.  
  261.       default:
  262.          pcsz = SkipNonWhiteSpace(pcsz);
  263.          break;
  264.    }
  265.  
  266.    return(pcsz);
  267. }
  268.  
  269.  
  270. //
  271. // Display a printf()-style message box.
  272. //
  273. static BOOL MyMessageBox(HWND hwndParent, UINT uStyle, LPCSTR pcszFormat, ...)
  274. {
  275.    char szMsg[1024];
  276.    va_list valArgs;
  277.  
  278.    // Lamely assume that wvsprintf() won't overflow szMsg[].
  279.  
  280.    va_start(valArgs, pcszFormat);
  281.    wvsprintf(szMsg, pcszFormat, valArgs);
  282.    va_end(valArgs);
  283.  
  284.    return(MessageBox(hwndParent, szMsg, s_cszMsgBoxTitle, uStyle));
  285. }
  286.  
  287.  
  288. //
  289. // Create the Java VM Debug key.
  290. //
  291. static BOOL CreateDebugKey(void)
  292. {
  293.     BOOL bResult;
  294.     DWORD dwDisposition;
  295.     HKEY hkeyDebug;
  296.  
  297.     bResult = (RegCreateKeyEx(HKEY_LOCAL_MACHINE, s_cszDebugKey, 0, NULL, 0, KEY_WRITE, NULL, &hkeyDebug, &dwDisposition)
  298.               == ERROR_SUCCESS);
  299.  
  300.     if (bResult)
  301.       RegCloseKey(hkeyDebug);
  302.  
  303.    return(bResult);
  304. }
  305.  
  306.  
  307. //
  308. // Delete the Java VM Debug key.
  309. //
  310. static BOOL DeleteDebugKey(void)
  311. {
  312.     return(RegDeleteKey(HKEY_LOCAL_MACHINE, s_cszDebugKey) == ERROR_SUCCESS);
  313. }
  314.  
  315.  
  316. /****************************** Public Functions *****************************/
  317.  
  318.  
  319. #pragma warning(disable:4100)    // "unreferenced formal parameter" warning
  320.  
  321. int __cdecl main(int argc, char *argv[])
  322. {
  323.    HRESULT hr;
  324.  
  325.    // Initialize OLE on this thread.
  326.  
  327.    hr = CoInitialize(NULL);
  328.  
  329.    if (SUCCEEDED(hr))
  330.    {
  331.        IRemoteDebugManager *pirdm;
  332.  
  333.        // Create a RemoteJavaDebugManager from JDbgMgr.exe to initiate debugging.
  334.  
  335.        hr = CoCreateInstance(CLSID_RemoteJavaDebugManager, NULL,
  336.                              CLSCTX_LOCAL_SERVER, IID_IRemoteDebugManager,
  337.                              (PVOID *)&pirdm);
  338.  
  339.        if (hr == S_OK)
  340.        {
  341.            JavaDebugger *pjd;
  342.  
  343.            // Create a JavaDebugger object to run a simple debugging session.
  344.  
  345.            pjd = new(JavaDebugger);
  346.  
  347.            if (pjd)
  348.            {
  349.                hr = pjd->Initialize(pirdm);
  350.  
  351.                if (hr == S_OK)
  352.                {
  353.                    hr = pjd->Debug(s_cszDebugClass);
  354.  
  355.                    pjd->Terminate();
  356.                }
  357.  
  358.                pjd->Release();
  359.                pjd = NULL;
  360.            }
  361.            else
  362.                hr = E_OUTOFMEMORY;
  363.  
  364.            pirdm->Release();
  365.            pirdm = NULL;
  366.        }
  367.  
  368.        // Uninitialize OLE on this thread.
  369.  
  370.        CoUninitialize();
  371.    }
  372.  
  373.    return(hr);
  374. }
  375.  
  376. #pragma warning(default:4100)    // "unreferenced formal parameter" warning
  377.  
  378.  
  379. /********************************** Methods **********************************/
  380.  
  381.  
  382. JavaDebugger::JavaDebugger(void)
  383. {
  384.    m_pirdm = NULL;
  385.    m_pirp = NULL;
  386.    m_pwszDebugClass = NULL;
  387.  
  388.    return;
  389. }
  390.  
  391.  
  392. JavaDebugger::~JavaDebugger(void)
  393. {
  394.    Terminate();
  395.  
  396.    return;
  397. }
  398.  
  399.  
  400. HRESULT JavaDebugger::Initialize(IRemoteDebugManager *pirdm)
  401. {
  402.    HRESULT hr;
  403.  
  404.    // Register this JavaDebugger's callback with the debug manager so it is notified when its debuggee target class is run.
  405.  
  406.    hr = pirdm->RegisterCallback(this);
  407.  
  408.    if (hr == S_OK)
  409.    {
  410.       m_pirdm = pirdm;
  411.       m_pirdm->AddRef();
  412.    }
  413.  
  414.    return(hr);
  415. }
  416.  
  417.  
  418. void JavaDebugger::Terminate(void)
  419. {
  420.    if (m_pirdm)
  421.    {
  422.       // Detach this JavaDebugger from the debug manager.
  423.  
  424.       m_pirdm->Detach();
  425.  
  426.       m_pirdm->Release();
  427.       m_pirdm = NULL;
  428.    }
  429.  
  430.    SAFE_DELETE(m_pwszDebugClass);
  431.  
  432.    return;
  433. }
  434.  
  435.  
  436. //
  437. // Run a message loop on this thread until a WM_QUIT message is encountered.
  438. //
  439. UINT JavaDebugger::RunMessageLoop(void)
  440. {
  441.    MSG msg;
  442.  
  443.    // No accelerators to load.
  444.  
  445.    // Get and dispatch messages until a WM_QUIT message is received.
  446.  
  447.    ZeroMemory(&msg, sizeof(msg));
  448.  
  449.    while (GetMessage(&msg, NULL, 0, 0))
  450.    {
  451.       // Translate virtual key codes.
  452.  
  453.       TranslateMessage(&msg);
  454.  
  455.       // Dispatch message to target window.
  456.  
  457.       DispatchMessage(&msg);
  458.    }
  459.  
  460.    return(msg.wParam);
  461. }
  462.  
  463.  
  464. //
  465. // Terminate any message loop running on this thread.
  466. //
  467. void JavaDebugger::QuitMessageLoop(UINT uResult)
  468. {
  469.    PostQuitMessage(uResult);
  470.  
  471.    return;
  472. }
  473.  
  474.  
  475. //
  476. // Initiate a simple debugging session.
  477. //
  478. HRESULT JavaDebugger::Debug(LPCSTR pcszDebugClass)
  479. {
  480.    HRESULT hr;
  481.  
  482.    // Create the Java VM Debug key to enable Java debugging.
  483.  
  484.    if (CreateDebugKey())
  485.    {
  486.       // Remember the debuggee class name.
  487.  
  488.       SAFE_DELETE(m_pwszDebugClass);
  489.  
  490.       hr = ANSIToUnicode(pcszDebugClass, &m_pwszDebugClass);
  491.  
  492.       if (hr == S_OK)
  493.       {
  494.          LPCSTR pcszCmdLine;
  495.          STARTUPINFO si;
  496.          PROCESS_INFORMATION pi;
  497.  
  498.          // Treat our command line arguments as the command line to run the debuggee class.
  499.  
  500.          pcszCmdLine = SkipWhiteSpace(SkipPossiblyQuotedArg(GetCommandLine()));
  501.  
  502.          ZeroMemory(&si, sizeof(si));
  503.          si.cb = sizeof(si);
  504.  
  505.          // Start the debuggee class process suspended so we can get its process ID before it executes.
  506.  
  507.          hr = CreateProcess(NULL, (LPSTR)pcszCmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi) ? S_OK : E_FAIL;
  508.  
  509.          if (hr == S_OK)
  510.          {
  511.             HRESULT hrResume;
  512.  
  513.             // Ask the debug manager to notify us when the debuggee class is run.
  514.  
  515.             hr = m_pirdm->RequestCreateEvent(m_pwszDebugClass, pi.dwProcessId);
  516.  
  517.             // Resume the debuggee class process to begin debugging.
  518.  
  519.             hrResume = (ResumeThread(pi.hThread) != 0xffffffff) ? S_OK : E_FAIL;
  520.  
  521.             if (hr == S_OK)
  522.                hr = hrResume;
  523.  
  524.             CloseHandle(pi.hProcess);
  525.             CloseHandle(pi.hThread);
  526.  
  527.             // Run a message loop to dispatch OLE RPC messages.
  528.  
  529.             RunMessageLoop();
  530.          }
  531.       }
  532.  
  533.       // Delete the Java VM Debug key, if it hasn't already been deleted, to disable Java debugging.
  534.  
  535.       DeleteDebugKey();
  536.    }
  537.  
  538.    return(hr);
  539. }
  540.  
  541.  
  542. HRESULT STDMETHODCALLTYPE JavaDebugger::QueryInterface(REFIID riid,
  543.                                                        PVOID *ppvObject)
  544. {
  545.     HRESULT hr = S_OK;
  546.  
  547.     if (riid == IID_IRemoteDebugManagerCallback)
  548.        *ppvObject = SAFE_CAST(IRemoteDebugManagerCallback *, this);
  549.     else if (riid == IID_IRemoteProcessCallback)
  550.        *ppvObject = SAFE_CAST(IRemoteProcessCallback *, this);
  551.     else if (riid == IID_IUnknown)
  552.        *ppvObject = SAFE_CAST(IUnknown *, (IRemoteDebugManagerCallback *)this);
  553.     else
  554.     {
  555.        *ppvObject = NULL;
  556.        hr = E_NOINTERFACE;
  557.     }
  558.  
  559.     if (hr == S_OK)
  560.         AddRef();
  561.  
  562.     return(hr);
  563. }
  564.  
  565.  
  566. //
  567. // Debugger event notification methods return an HRESULT as follows:
  568. //
  569. //      S_FALSE     Continue execution.
  570. //
  571. //      S_OK        Suspend execution of all threads in this VM until an
  572. //                  IRemoteThread method is called on this thread to resume
  573. //                  execution.
  574. //
  575. //      E_...       Error.
  576. //
  577.  
  578. #pragma warning(disable:4100)    // "unreferenced formal parameter" warning
  579.  
  580. HRESULT STDMETHODCALLTYPE JavaDebugger::ProcessCreateEvent(
  581.                                                     IRemoteProcess *pirpNew,
  582.                                                     IRemoteProcess *pirpParent)
  583. {
  584.    HRESULT hr;
  585.  
  586.    // Register this JavaDebugger's callback with the Java VM so it is notified when interesting events occur in the debuggee.
  587.  
  588.    hr = pirpNew->RegisterCallback(this);
  589.  
  590.    if (hr == S_OK)
  591.    {
  592.       m_pirp = pirpNew;
  593.       m_pirp->AddRef();
  594.    }
  595.  
  596.    MyMessageBox(NULL, (MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND), "Process created.");
  597.  
  598.    // Delete the Java VM Debug key to disable Java debugging.
  599.  
  600.    DeleteDebugKey();
  601.  
  602.    return(S_FALSE);
  603. }
  604.  
  605.  
  606. HRESULT STDMETHODCALLTYPE JavaDebugger::DebugStringEvent(IRemoteThread *pirth, LPCWSTR pcwszDebugMsg)
  607. {
  608.    return(S_FALSE);
  609. }
  610.  
  611.  
  612. HRESULT STDMETHODCALLTYPE JavaDebugger::CodeBreakpointEvent(IRemoteThread *pirth)
  613. {
  614.    HRESULT hr;
  615.    IRemoteStackFrame *pirsf;
  616.  
  617.    // Get the method object from the current thread's current stack frame.
  618.  
  619.    hr = pirth->GetCurrentFrame(&pirsf);
  620.  
  621.    if (hr == S_OK)
  622.    {
  623.       IRemoteContainerObject *pirco;
  624.  
  625.       hr = pirsf->GetMethodObject(&pirco);
  626.  
  627.       if (hr == S_OK)
  628.       {
  629.          IRemoteField *pirf;
  630.  
  631.          // Get the method field from the method object.
  632.  
  633.          hr = pirco->GetType(&pirf);
  634.  
  635.          if (hr == S_OK)
  636.          {
  637.             IRemoteMethodField *pirmf;
  638.  
  639.             hr = pirf->QueryInterface(IID_IRemoteMethodField, (PVOID *)&pirmf);
  640.  
  641.             if (hr == S_OK)
  642.             {
  643.                // Clear the breakpoint, and continue execution.
  644.  
  645.                hr = pirmf->ClearBreakpoint(s_ulcBreakpointPC);
  646.  
  647.                if (hr == S_OK)
  648.                   MyMessageBox(NULL, (MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND), "Hit breakpoint %ls.%ls().%lu.",
  649.                                m_pwszDebugClass,
  650.                                s_cwszDebugMethod,
  651.                                s_ulcBreakpointPC);
  652.  
  653.                pirmf->Release();
  654.                pirmf = NULL;
  655.             }
  656.  
  657.             pirf->Release();
  658.             pirf = NULL;
  659.          }
  660.  
  661.          pirco->Release();
  662.          pirco = NULL;
  663.       }
  664.  
  665.       pirsf->Release();
  666.       pirsf = NULL;
  667.    }
  668.  
  669.    return(S_FALSE);
  670. }
  671.  
  672.  
  673. HRESULT STDMETHODCALLTYPE JavaDebugger::DataBreakpointEvent(IRemoteThread *pirth, IRemoteObject *piro)
  674. {
  675.    return(S_FALSE);
  676. }
  677.  
  678.  
  679. HRESULT STDMETHODCALLTYPE JavaDebugger::ExceptionEvent(IRemoteThread *pirth, IRemoteClassField *pircfException, EXCEPTIONKIND exk)
  680. {
  681.    return(S_FALSE);
  682. }
  683.  
  684.  
  685. HRESULT STDMETHODCALLTYPE JavaDebugger::StepEvent(IRemoteThread *pirth)
  686. {
  687.    return(S_FALSE);
  688. }
  689.  
  690.  
  691. HRESULT STDMETHODCALLTYPE JavaDebugger::CanStopEvent(IRemoteThread *pirth)
  692. {
  693.    return(S_FALSE);
  694. }
  695.  
  696.  
  697. HRESULT STDMETHODCALLTYPE JavaDebugger::BreakEvent(IRemoteThread *pirth)
  698. {
  699.    return(S_FALSE);
  700. }
  701.  
  702.  
  703. HRESULT STDMETHODCALLTYPE JavaDebugger::ThreadCreateEvent(IRemoteThread *pirth)
  704. {
  705.    return(S_FALSE);
  706. }
  707.  
  708.  
  709. HRESULT STDMETHODCALLTYPE JavaDebugger::ThreadDestroyEvent(IRemoteThread *pirth)
  710. {
  711.    return(S_FALSE);
  712. }
  713.  
  714.  
  715. HRESULT STDMETHODCALLTYPE JavaDebugger::ThreadGroupCreateEvent(IRemoteThread *pirth, IRemoteThreadGroup *pirthg)
  716. {
  717.    return(S_FALSE);
  718. }
  719.  
  720.  
  721. HRESULT STDMETHODCALLTYPE JavaDebugger::ThreadGroupDestroyEvent(IRemoteThread *pirth, IRemoteThreadGroup *pirthg)
  722. {
  723.    return(S_FALSE);
  724. }
  725.  
  726.  
  727. HRESULT STDMETHODCALLTYPE JavaDebugger::ClassLoadEvent(IRemoteThread *pirth, IRemoteClassField *pircfClass)
  728. {
  729.    LPWSTR pwszClassName;
  730.  
  731.    // Get the name of the loaded class.
  732.  
  733.    if (pircfClass->GetName(&pwszClassName) == S_OK)
  734.    {
  735.       // Is this the class that a breakpoint is to be set in?
  736.  
  737.       if (! wcscmp(pwszClassName, m_pwszDebugClass))
  738.       {
  739.          IJavaEnumRemoteField *pijerf;
  740.  
  741.          // Yes.  Get the method field for the method to set a breakpoint in.
  742.  
  743.          if (pircfClass->GetFields(&pijerf, FIELD_KIND_METHOD, 0, s_cwszDebugMethod) == S_OK)
  744.          {
  745.             IRemoteField *pirf;
  746.             ULONG ulcFetched;
  747.  
  748.             if (pijerf->Next(1, &pirf, &ulcFetched) == S_OK)
  749.             {
  750.                IRemoteMethodField *pirmf;
  751.  
  752.                if (pirf->QueryInterface(IID_IRemoteMethodField, (PVOID *)&pirmf) == S_OK)
  753.                {
  754.                   // Set the breakpoint, and continue execution.
  755.  
  756.                   pirmf->SetBreakpoint(s_ulcBreakpointPC);
  757.  
  758.                   pirmf->Release();
  759.                   pirmf = NULL;
  760.                }
  761.  
  762.                pirf->Release();
  763.                pirf = NULL;
  764.             }
  765.  
  766.             pijerf->Release();
  767.             pijerf = NULL;
  768.          }
  769.       }
  770.  
  771.       CoTaskMemFree(pwszClassName);
  772.       pwszClassName = NULL;
  773.    }
  774.  
  775.    return(S_FALSE);
  776. }
  777.  
  778.  
  779. HRESULT STDMETHODCALLTYPE JavaDebugger::ClassUnloadEvent(IRemoteThread *pirth, IRemoteClassField *pircfClass)
  780. {
  781.    return(S_FALSE);
  782. }
  783.  
  784.  
  785. HRESULT STDMETHODCALLTYPE JavaDebugger::ProcessDestroyEvent(IRemoteThread *pirth)
  786. {
  787.    // Detach this JavaDebugger from the Java VM.
  788.  
  789.    m_pirp->Detach();
  790.  
  791.    m_pirp->Release();
  792.    m_pirp = NULL;
  793.  
  794.    MyMessageBox(NULL, (MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND), "Process destroyed.");
  795.  
  796.    // Quit the message loop, and end the debugging session.
  797.  
  798.    QuitMessageLoop(0);
  799.  
  800.    return(S_FALSE);
  801. }
  802.  
  803.  
  804. HRESULT STDMETHODCALLTYPE JavaDebugger::TraceEvent(IRemoteThread *pirth)
  805. {
  806.    return(S_FALSE);
  807. }
  808.  
  809.  
  810. HRESULT STDMETHODCALLTYPE JavaDebugger::LoadCompleteEvent(IRemoteThread *pirth)
  811. {
  812.    return(S_FALSE);
  813. }
  814.  
  815. #pragma warning(default:4100)    // "unreferenced formal parameter" warning
  816.  
  817.